package org.summer.lawyer.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.summer.common.core.exception.ServiceException;
import org.summer.common.core.utils.MapstructUtils;
import org.summer.common.mybatis.core.page.PageQuery;
import org.summer.common.mybatis.core.page.TableDataInfo;
import org.summer.common.satoken.utils.LoginHelper;
import org.summer.lawyer.constant.SystemConstants;
import org.summer.lawyer.domain.Spu;
import org.summer.lawyer.domain.vo.category.CategoryVo;
import org.summer.lawyer.domain.vo.spu.SpuCreateVo;
import org.summer.lawyer.domain.vo.spu.SpuDetailVo;
import org.summer.lawyer.domain.vo.spu.SpuUpdateVo;
import org.summer.lawyer.domain.vo.spu.SpuVo;
import org.summer.lawyer.mapper.SpuMapper;
import org.summer.lawyer.service.ICategoryService;
import org.summer.lawyer.service.ISpuService;
import org.summer.system.domain.vo.SysDictDataVo;
import org.summer.system.domain.vo.SysOssVo;
import org.summer.system.service.ISysDictDataService;
import org.summer.system.service.ISysOssService;

import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 *
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class SpuServiceImpl extends ServiceImpl<SpuMapper, Spu> implements ISpuService {

    private final ICategoryService categoryService;

    private final ISysDictDataService sysDictDataService;

    private final ISysOssService sysOssService;

    @Override
    public TableDataInfo<SpuVo> selectListPage(SpuVo vo, PageQuery pageQuery) {
        Map<String, Object> params = vo.getParams();
        LambdaQueryWrapper<Spu> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(vo.getCategoryId() != null, Spu::getCategoryId, vo.getCategoryId())
                .eq(StrUtil.isNotBlank(vo.getSpuStatus()), Spu::getSpuStatus, vo.getSpuStatus())
                .like(StrUtil.isNotBlank(vo.getSpuName()), Spu::getSpuName, vo.getSpuName())
                .orderByDesc(Spu::getSpuId);
        Page<SpuVo> page = baseMapper.selectVoPage(pageQuery.build(), queryWrapper);
        return TableDataInfo.build(page);
    }

    @Override
    public TableDataInfo<SpuDetailVo> selectPageSpuDetailList(SpuDetailVo vo, PageQuery pageQuery) {
        QueryWrapper<Spu> queryWrapper = Wrappers.query();
        queryWrapper.eq(vo.getCategoryId() != null, "s.category_id", vo.getCategoryId())
                .eq(vo.getSpuId() != null, "s.spu_id", vo.getSpuId())
                .eq(vo.getCategoryParentId() != null, "s.category_parent_id", vo.getCategoryParentId())
                .eq(StrUtil.isNotBlank(vo.getSpuStatus()), "s.spu_status", vo.getSpuStatus())
                .like(StrUtil.isNotBlank(vo.getSpuName()), "s.spu_name", vo.getSpuName())
                .orderByDesc("s.spu_id");
            if(PageQuery.DEFAULT_PAGE_SIZE == pageQuery.getPageSize()){
                return TableDataInfo.build(baseMapper.selectSpuDetailList(queryWrapper));
            }
        Page<SpuDetailVo> page = baseMapper.selectPageSpuDetailList(pageQuery.build(), queryWrapper);
        return TableDataInfo.build(page);

    }

    /**
     * 查询商品信息
     *
     * @param spuId 主键
     * @return 商品信息
     */
    @Override
    public SpuVo selectSpuVoById(Long spuId) {
        return baseMapper.selectVoById(spuId);
    }

    /**
     * 分页查询商品信息列表
     *
     * @param vo        查询条件
     * @param pageQuery 分页参数
     * @return 商品信息分页列表
     */
    @Override
    public TableDataInfo<SpuVo> selectPageList(SpuVo vo, PageQuery pageQuery) {
        LambdaQueryWrapper<Spu> lqw = buildQueryWrapper(vo);
        Page<SpuVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询符合条件的商品信息列表
     *
     * @param vo 查询条件
     * @return 商品信息列表
     */
    @Override
    public List<SpuVo> selectSpuVoList(SpuVo vo) {
        LambdaQueryWrapper<Spu> lqw = Wrappers.lambdaQuery();
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<Spu> buildQueryWrapper(SpuVo vo) {
        Map<String, Object> params = vo.getParams();
        LambdaQueryWrapper<Spu> lqw = Wrappers.lambdaQuery();
      //  lqw.eq(vo.getCategoryId() != null, Spu::getCategoryId, vo.getCategoryId());
        lqw.and(vo.getCategoryId() != null, w -> {
            List<Long> ids = categoryService.selectIdsByParentId(vo.getCategoryId());
            w.in(Spu::getCategoryId, ids);

        });
        lqw.like(StrUtil.isNotBlank(vo.getCategoryName()), Spu::getCategoryName, vo.getCategoryName());
        lqw.eq(vo.getCategoryParentId() != null, Spu::getCategoryParentId, vo.getCategoryParentId());
        lqw.like(StrUtil.isNotBlank(vo.getSpuName()), Spu::getSpuName, vo.getSpuName());
        lqw.eq(StrUtil.isNotBlank(vo.getSubtitle()), Spu::getSubtitle, vo.getSubtitle());
        lqw.eq(StrUtil.isNotBlank(vo.getMainImgUrl()), Spu::getMainImgUrl, vo.getMainImgUrl());
        lqw.eq(StrUtil.isNotBlank(vo.getSecImgUrl()), Spu::getSecImgUrl, vo.getSecImgUrl());
        lqw.eq(vo.getPriceFee() != null, Spu::getPriceFee, vo.getPriceFee());
        lqw.eq(vo.getMarketPriceFee() != null, Spu::getMarketPriceFee, vo.getMarketPriceFee());
        lqw.eq(StrUtil.isNotBlank(vo.getSpuStatus()), Spu::getSpuStatus, vo.getSpuStatus());
        lqw.eq(StrUtil.isNotBlank(vo.getSaleTrack()), Spu::getSaleTrack, vo.getSaleTrack());
        lqw.eq(StrUtil.isNotBlank(vo.getSpuDesc()), Spu::getSpuDesc, vo.getSpuDesc());
        lqw.eq(StrUtil.isNotBlank(vo.getSpuDetail()), Spu::getSpuDetail, vo.getSpuDetail());
        return lqw;
    }

    @Override
    public SpuDetailVo selectSpuDetailVoById(Long id) {
        QueryWrapper<Spu> lqw = Wrappers.query();
        lqw.eq("s.spu_id", id);
        return baseMapper.selectSpuDetailVoById(lqw);
    }

    @Override
    public void saveSpu(SpuCreateVo vo) {

    }

    @Override
    public void updateSpu(SpuUpdateVo vo) {

    }

    @DSTransactional(rollbackFor = Exception.class)
    @Override
    public void deleteSpuByIds(Collection<Long> ids) {
        if (CollUtil.isEmpty(ids)) {
            throw new ServiceException("主键不能为空");
        }
        baseMapper.deleteBatchIds(ids);
    }

    /**
     * 新增商品信息
     *
     * @param vo 商品信息
     * @return 是否新增成功
     */
    @Override
    public Boolean insertByVo(SpuCreateVo vo) {
        Spu add = MapstructUtils.convert(vo, Spu.class);
        validEntityBeforeSave(add);
        //获取分类信息
        CategoryVo categoryVo = categoryService.selectCategoryVoById(vo.getCategoryId());
        if(categoryVo == null){
            throw new ServiceException("不能选择顶级分类");
        }
        add.setCategoryName(categoryVo.getCategoryName());
        add.setCategoryParentId(categoryVo.getParentId());
        add.setCreateTime(DateUtil.date());
        add.setUpdateTime(DateUtil.date());
        if(LoginHelper.getUserId()!= null){
            add.setCreateBy(LoginHelper.getUserId());
            add.setUpdateBy(LoginHelper.getUserId());
        }
        add.setAttachmentId(add.getAttachmentId());
        //转换url
        if(StrUtil.isNotBlank(add.getAttachmentId())){
           SysOssVo ossVo =sysOssService.getById(Long.parseLong(add.getAttachmentId()));
           if(ossVo != null){
               add.setUrl(ossVo.getUrl());
           }
        }
        //是否需要指派律师
        SysDictDataVo dictDataVo = sysDictDataService.selectDictDataVo(SystemConstants.SERVICE_CATEGORY,String.valueOf(categoryVo.getParentId()));
        if(dictDataVo != null && SystemConstants.ACTIVE.equals(dictDataVo.getCssClass())){
            add.setDispatchable(SystemConstants.ACTIVE);
        }
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            vo.setSpuId(add.getSpuId());
        }
        return flag;
    }

    /**
     * 修改商品信息
     *
     * @param vo 商品信息
     * @return 是否修改成功
     */
    @Override
    public Boolean updateByVo(SpuUpdateVo vo) {
        Spu update = MapstructUtils.convert(vo, Spu.class);
        //获取分类信息
        CategoryVo categoryVo = categoryService.selectCategoryVoById(vo.getCategoryId());
        if(categoryVo == null){
            throw new ServiceException("不能选择顶级分类");
        }
        update.setCategoryName(categoryVo.getCategoryName());
        update.setCategoryParentId(categoryVo.getParentId());
        update.setAttachmentId(update.getSubtitle());
        update.setAttachmentId(update.getAttachmentId());
        //转换url
        if(StrUtil.isNotBlank(update.getAttachmentId())){
            SysOssVo ossVo =sysOssService.getById(Long.parseLong(update.getAttachmentId()));
            if(ossVo != null){
                update.setUrl(ossVo.getUrl());
            }
        }
        update.setUpdateTime(DateUtil.date());
        if(LoginHelper.getUserId()!= null){
            update.setUpdateBy(LoginHelper.getUserId());
        }
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(Spu entity) {
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 校验并批量删除商品信息信息
     *
     * @param ids     待删除的主键集合
     * @param isValid 是否进行有效性校验
     * @return 是否删除成功
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }
}
